﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace iTPS.Service.Core.Http
{
    public class HttpClientHelper
    {
        private readonly IHttpClientFactory _httpClientFactory;


        public const string ContentTypeJson = "application/json";
        public const string ContentTypeText = "text/plain";
        public const string ContentTypeApplicationForm = "application/x-www-form-urlencoded";

        public HttpClientHelper(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public async Task<string> GetAsync(Uri uri)
        {
            var client = _httpClientFactory.CreateClient();
            var request = new HttpRequestMessage()
            {
                RequestUri = uri,
                Method = HttpMethod.Get,
            };
            var response = await client.SendAsync(request);
            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new iTPSException(EnumiTPSException.Http请求错误, $"Post to {request.RequestUri} error,Status code:{response.StatusCode}");
            }
            var result = await response.Content.ReadAsStringAsync();
            return result;
        }

        public async Task<string> GetStringAsync(string clientName, Uri requestUri)
        {
            var client = _httpClientFactory.CreateClient(clientName);
            var result = await client.GetStringAsync(requestUri);
            return result;
        }

        public async Task<HttpResponseMessage> PostStringAsync(string clientName, string data, Uri requestUri, Dictionary<string, string> headers, string contentType = ContentTypeText)
        {
            var client = _httpClientFactory.CreateClient(clientName);
            var content = new StringContent(data);
            content.Headers.Clear();
            if (!string.IsNullOrWhiteSpace(contentType))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
            }
            //content.Headers.ContentLength = data.Length;
            content.Headers.Add("charset", "utf-8");
            if (headers != null)
            {
                foreach (var item in headers)
                {
                    content.Headers.Add(item.Key, item.Value);
                }
            }
            var requestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Post,
                Content = content
            };
            requestMessage.RequestUri = requestUri;

            var responseMessage = await client.SendAsync(requestMessage);
            if (responseMessage.StatusCode != HttpStatusCode.OK)
            {
                throw new iTPSException(EnumiTPSException.Http请求错误, $"Post to {requestMessage.RequestUri} error,Status code:{responseMessage.StatusCode}");
            }
            return responseMessage;
        }

        public async Task<HttpResponseMessage> PostByteAsync(string clientName, byte[] dataByte, Uri requestUri, string contentType = ContentTypeApplicationForm)
        {
            var client = _httpClientFactory.CreateClient(clientName);
            var content = new ByteArrayContent(dataByte);
            content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
            content.Headers.ContentLength = dataByte.Length;
            content.Headers.ContentType.CharSet = "utf-8";
            var requestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Post,
                Content = content
            };
            requestMessage.RequestUri = requestUri;
            var responseMessage = await client.SendAsync(requestMessage);
            if (responseMessage.StatusCode != HttpStatusCode.OK)
            {
                throw new iTPSException(EnumiTPSException.Http请求错误, $"Post to {requestMessage.RequestUri} error,Status code:{responseMessage.StatusCode}");
            }
            return responseMessage;
        }

        public async Task<T> PostJsonAsync<T>(string clientName, object data, Uri requestUri, Dictionary<string, string> headers, string contenTypeJson = ContentTypeJson)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            var dataJsonString = JsonConvert.SerializeObject(data);
            var response = await PostStringAsync(clientName, dataJsonString, requestUri, headers, contenTypeJson);
            var responseContentString = await response.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<T>(responseContentString);
        }

        public async Task<T> PostStringResponseJsonAsync<T>(string clientName, string data, Uri requestUri, Dictionary<string, string> headers, string contenTypeJson = ContentTypeJson)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            var response = await PostStringAsync(clientName, data, requestUri, headers, contenTypeJson);
            var responseContentString = await response.Content.ReadAsStringAsync();

            return JsonConvert.DeserializeObject<T>(responseContentString);
        }

        public async Task<T> PostByteResponseJsonAsync<T>(string clientName, byte[] dataByte, Uri requestUri, string contenTypeJson = ContentTypeJson)
        {
            if (dataByte == null)
            {
                throw new ArgumentNullException(nameof(dataByte));
            }

            var response = await PostByteAsync(clientName, dataByte, requestUri, contenTypeJson);
            var responseContentString = await response.Content.ReadAsStringAsync();

            return JsonConvert.DeserializeObject<T>(responseContentString);

        }


        public async Task<HttpZeusWebApiResponse<T>> PostZeusAysnc<T>(string clientName, object data, Uri requestUri, Dictionary<string, string> headers = null)
        {
            return await PostJsonAsync<HttpZeusWebApiResponse<T>>(clientName, data, requestUri, headers);
        }
    }
}
